﻿using System;
using System.Web.Mvc;
using EasyUIMvc.ComboBox;
using EasyUIMvc.Tooltip;
using EasyUIMvc.Tree;
using EasyUIMvc.Window;

namespace EasyUIMvc
{
    public static class HtmHelperExtension
    {
        // Summary:
        //     Provides access to helper methods allowing you to render individual DevExpress
        //     ASP.NET MVC extensions.
        //
        // Parameters:
        //   helper:
        //     A System.Web.Mvc.HtmlHelper object representing the HTML helper instance
        //     that this method extends.
        //
        // Returns:
        //     An DevExpress.Web.Mvc.UI.ExtensionsFactory object containing helper methods
        //     to render DevExpress MVC extensions.
        public static ExtensionsFactory EasyUI(this HtmlHelper helper)
        {
            return ExtensionsFactory.Instance;
        }
    }

    public class ExtensionsFactory
    {
        private static ExtensionsFactory _instance;
        public static ExtensionsFactory Instance
        {
            get { return _instance ?? (_instance = new ExtensionsFactory()); }
        }

        public MenuExtension Menu(Action<MenuSettings> method)
        {
            return CreateExtension<MenuExtension, MenuSettings>(method);
        }
        public MenuButtonExtension MenuButton(Action<MenuButtonSettings> method)
        {
            return CreateExtension<MenuButtonExtension, MenuButtonSettings>(method);
        }
        public LinkButtonExtension LinkButton(Action<LinkButtonSettings> method)
        {
            return CreateExtension<LinkButtonExtension, LinkButtonSettings>(method);
        }
        public ComboBoxExtension ComboBox(Action<ComboBoxSettings> method)
        {
            return CreateExtension<ComboBoxExtension, ComboBoxSettings>(method);
        }
        public CalendarExtension Calendar(Action<CalendarSettings> method)
        {
            return CreateExtension<CalendarExtension, CalendarSettings>(method);
        }
        public WindowLayoutExtension Window(Action<WindowSettings> method)
        {
            return CreateExtension<WindowLayoutExtension, WindowSettings>(method);
        }

        /// <summary>
        /// Created: LinhMC
        /// Windows the base.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public WindowBaseExtension WindowBase(Action<WindowSettings> method)
        {
            return CreateExtension<WindowBaseExtension, WindowSettings>(method);
        }

        /// <summary>
        /// Created: LinhMC
        /// Accordions the specified method.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public AccordionExtension Accordion(Action<AccordionSettings> method)
        {
            return CreateExtension<AccordionExtension, AccordionSettings>(method);
        }

        /// <summary>
        /// Created: LinhMC
        /// Dialogs the toolbar.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public DialogToolbarExtension DialogToolbar(Action<DialogToolbarSettings> method)
        {
            return CreateExtension<DialogToolbarExtension, DialogToolbarSettings>(method);
        }

        /// <summary>
        /// Created: LinhMC
        /// Comboes the grid.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public ComboGridExtension ComboGrid(Action<ComboGridSettings> method)
        {
            return CreateExtension<ComboGridExtension, ComboGridSettings>(method);
        }

        /// <summary>
        /// Created: LinhMC
        /// Trees the grid.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public TreeGridExtension TreeGrid(Action<TreeGridSettings> method)
        {
            return CreateExtension<TreeGridExtension, TreeGridSettings>(method);
        }

        /// <summary>
        /// Tooltips the hover link.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public HoverLinkExtension TooltipHoverLink(Action<TooltipHoverLinkSettings> method)
        {
            return CreateExtension<HoverLinkExtension, TooltipHoverLinkSettings>(method);
        }

        /// <summary>
        /// Tooltips the hover text.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public HoverTextExtension TooltipHoverText(Action<TooltipHoverTextSettings> method)
        {
            return CreateExtension<HoverTextExtension, TooltipHoverTextSettings>(method);
        }

        public MultipleComboTreeExtension MultipleComboTree(Action<MultipleComboTreeSettings> method)
        {
            return CreateExtension<MultipleComboTreeExtension, MultipleComboTreeSettings>(method);
        }

        public NumberBoxExtension NumberBox(Action<NumberBoxSettings> method)
        {
            return CreateExtension<NumberBoxExtension, NumberBoxSettings>(method);
        }

        public DataGridExtension DataGrid(Action<DataGridSettings> method)
        {
            return CreateExtension<DataGridExtension, DataGridSettings>(method);
        }
        public TreeExtension Tree(Action<TreeSettings> method)
        {
            return CreateExtension<TreeExtension, TreeSettings>(method);
        }

        internal static TE CreateExtension<TE, TS>(Action<TS> method)
            where TE : ExtensionBase
            where TS : SettingsBase, new()
        {
            var settings = Activator.CreateInstance<TS>();
            method(settings);
            return (TE)CreateExtension(typeof(TE), settings);
        }

        internal static ExtensionBase CreateExtension(Type type, SettingsBase settings)
        {
            return (ExtensionBase)Activator.CreateInstance(type, new object[] { settings });
        }

    }

    public abstract class ExtensionBase
    {
        protected virtual TagBuilder GetTopTag(string tag, string cssCls,SettingsBase settings)
        {
            var top = new TagBuilder(tag);
            top.AddCssClass(cssCls);
            top.GenerateId(settings.Id);

            if (!string.IsNullOrWhiteSpace(settings.DataOptions))
            {
                top.Attributes.Add("data-options",settings.DataOptions);
            }

            return top;
        }

        /// <summary>
        /// Created: LinhMC
        /// Gets the inner tag.
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <param name="cssCls">The CSS CLS.</param>
        /// <param name="settings">The settings.</param>
        /// <returns></returns>
        protected virtual TagBuilder GetInnerTag(string tag, string cssCls, SettingsBase settings)
        {
            var inner = new TagBuilder(tag);
            inner.GenerateId(settings.Id);
            if (!string.IsNullOrEmpty(cssCls))
            {
                inner.AddCssClass(cssCls);
            }
            
            if (!string.IsNullOrWhiteSpace(settings.DataOptions))
            {
                inner.Attributes.Add("data-options", settings.DataOptions);
            }

            return inner;
        }

        /// <summary>
        /// Created: LinhMC
        /// Gets the inner tag.
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <param name="cssCls">The CSS CLS.</param>
        /// <param name="title">The title.</param>
        /// <param name="dataOption">The data option.</param>
        /// <param name="style">The style.</param>
        /// <returns></returns>
        protected virtual TagBuilder GetInnerTag(string tag, string cssCls, string title, string dataOption, string style)
        {
            var inner = new TagBuilder(tag);
            if (!string.IsNullOrEmpty(cssCls))
            {
                inner.AddCssClass(cssCls);
            }
            if (!string.IsNullOrEmpty(title))
            {
                inner.Attributes.Add("title", title);
            }

            if (!string.IsNullOrWhiteSpace(dataOption))
            {
                inner.Attributes.Add("data-options", dataOption);
            }
            if (!string.IsNullOrWhiteSpace(style))
            {
                inner.Attributes.Add("style", style);
            }

            return inner;
        }


        public abstract string GetScripts();
        public abstract MvcHtmlString GetHtml();
    }

    public abstract class SettingsBase
    {
        /// <summary>
        /// Ví dụ thẻ id html
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// Thẻ html được sử dụng để thiết lập tùy chọn thuộc tính dữ liệu 
        /// </summary>
        public string DataOptions { get; set; }
    }
}
